from logger import log
from unit import Unit
from threading import Thread
import time

SLOTS_PER_WORKER = 2

class Worker(Thread):
	def __init__(self, parent, slots = SLOTS_PER_WORKER):
		Thread.__init__(self)
		self.units = []
		self.maxSlots = slots
		self.parent = parent
		log('Created Worker')
		pass

	def getLoad(self):
		return len(self.units)

	def hasSlots(self):
		return len(self.units) < self.maxSlots

	def getMaxSlots(self):
		return self.maxSlots

	def addUnit(self, unit):
		self.units.append(unit)

	def drop(self, unit, reason):
		unit.disconnect()
		self.units.remove(unit)
		log('Unit %s dropped: %s'%(unit.ip,reason))
		self.parent.printInfo()

	def run(self):
		while True:
			now = time.time()
			for unit in self.units:
				if unit.lastContact + 5 < now:
					self.drop(unit, 'Ping timeout')
					continue

				if unit.dead:
					self.drop(unit, 'Unit dead (broken crash / close / pipe error / protocol error)')
					continue

				if unit.hasData():
					unit.read()

				# ...

				unit.processQueue()

			pass
			time.sleep(0.1)

	def broadcastEvent(self, event, exclude = [], map = None, target = None):
		for unit in self.units:
			if unit not in exclude:
				if (not map) or (unit.map == map and (target is None) or (unit.visible(target))):
#				unit.write(packet)
					unit.addEvent(event)

	def getUnits(self):
		return self.units
